/******************** (C) COPYRIGHT 2018 merafour ********************
* Author             : 冷月追风@merafour.blog.163.com
* Version            : V1.0.0
* Date               : 11/1/2019
* Description        : 数据存储接口.
********************************************************************************
* merafour.blog.163.com
* merafour@163.com
* github.com/Merafour
*******************************************************************************/
#ifndef CJSONSTORAGE_H
#define CJSONSTORAGE_H

#include <QDateTime>
#include <QMutex>
#include <stdint.h>
#include <string.h>
#include <malloc.h>
#include "cJSON.h"

//#include <QDebug>

class cJSONstorage
{
public:
    cJSONstorage(const char* _objName);
    ~cJSONstorage()
    {
        if(nullptr!=json_root) cJSON_Delete(json_root);
        //if(nullptr!=json_item) free(json_item);
    }

    char* open(const char *path);
    cJSON* opencJSON(const char *path);
    static int savecJSON(const char *path, const char* json_str);
    int savecJSON(const char *path, const cJSON* root);

//    void debug(void)
//    {
//        char* json_str;
//        json_str = cJSON_Print(json_root);
//        qDebug("json[%8d]: %s", count, json_str);
//        if(nullptr != json_str) free(json_str);
//        count++;
//    }
    int opencJSON(const char *path, cJSON* *root);
    int opencJSON(void)
    {
        cJSON* _root=nullptr;
        int ret=0;
        ret = opencJSON(objName, &_root);
        if(0==ret)
        {
//            free(json_root);
//            json_root = _root;
            cJSON_Delete(_root);
        }
        //add_item(QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss").toLocal8Bit().data());
        add_object("Time", QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss").toLocal8Bit().data());
        return ret;
    }
    const cJSON* get_root(void)
    {
        return json_root;
    }
    int save(void)
    {
#if 1
        if(0==savecJSON(objName, json_root))
        {
            free(json_root);
            json_root = cJSON_CreateObject();
            json_item = nullptr;
            //add_item(QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss").toLocal8Bit().data());
            add_object("Time", QDateTime::currentDateTime().toString("yyyy.MM.dd hh:mm:ss").toLocal8Bit().data());
            return 0;
        }
        return -1;
#else
        return savecJSON(objName, json_root);
#endif
    }
    void add_item(const char *string)
    {
        cJSON* item = cJSON_CreateObject();
        json_item = item;
        cJSON_AddItemToObject(json_root, string, item);
    }
    void add_branch_in_item(const char *string)
    {
        cJSON* item = cJSON_CreateObject();
        cJSON_AddItemToObject(json_item, string, item);
        json_history[4] = json_history[3];
        json_history[3] = json_history[2];
        json_history[2] = json_history[1];
        json_history[1] = json_history[0];
        json_history[0] = json_item;
        json_item = item;
    }
    void brack_last_branch(void)
    {
        json_item = json_history[0];
        json_history[0] = json_history[1];
        json_history[1] = json_history[2];
        json_history[2] = json_history[3];
        json_history[3] = json_history[4];
    }
    void add_array(const char* item_name, const double *numbers, int count)
    {
//        cJSON* objroot;
        if(nullptr==json_item) json_item = json_root;
//        objroot = cJSON_CreateArray();
//        cJSON_AddItemToArray(objroot, cJSON_CreateDoubleArray(numbers, count));
        cJSON_AddItemToObject(json_item, item_name, cJSON_CreateDoubleArray(numbers, count));
    }
    void add_object(const char *string, const char* object)
    {
        if(nullptr==json_item) json_item = json_root;
        cJSON_AddItemToObject(json_item, string, cJSON_CreateString(object));
    }
    void add_number(const char * const name, const double number)
    {
        if(nullptr==json_item) json_item = json_root;
        cJSON_AddNumberToObject(json_item, name, number);
    }

protected:
    cJSON *json_root;
    cJSON *json_item;
    cJSON *json_history[5];
    const char* get_objName(void)
    {
        return objName;
    }

private:
    char objName[64];
    static int create_cutover(const char *path);
    static uint32_t obj_count;
    QMutex mutex;
};

#endif // CJSONSTORAGE_H
